package state;

import particle.core.tools.Color;
import particle.core.tools.PMath;
import particle.core.tools.Rect;
import particle.core.view.Renderer;

public class Graphics {
  private Renderer g = null;
  private Rect clip = new Rect();

  public Graphics(Renderer g1) {
    this.g = g1;
  }

  public Renderer getSystemGraphics() {
    return g;
  }

  public void setColor(int RGB) {
    RGB = RGB | 0xFF000000;
    g.setFillColor(RGB);
    g.setTextColor(RGB);
    g.setStrokeColor(RGB);
  }

  public void fillRect(int x, int y, int width, int height) {
    g.drawRect(x, y, x + width, y + height);
  }

  protected int calculateX(int value, int anchor, int width) {
    switch (anchor) {
    case GameConstants.TOP_LEFT_ANCHOR:
    case GameConstants.VCENTER_LEFT_ANCHOR:
    case GameConstants.BOTTOM_LEFT_ANCHOR:
      return value;
    case GameConstants.TOP_HCENTER_ANCHOR:
    case GameConstants.CENTER_ANCHOR:
    case GameConstants.BOTTOM_HCENTER_ANCHOR:
      return value - width / 2;
    case GameConstants.TOP_RIGHT_ANCHOR:
    case GameConstants.VCENTER_RIGHT_ANCHOR:
    case GameConstants.BOTTOM_RIGHT_ANCHOR:
      return value - width;
    default:
      return value;
    }
  }

  protected int calculateY(int value, int anchor, int height) {
    switch (anchor) {
    case GameConstants.TOP_LEFT_ANCHOR:
    case GameConstants.TOP_HCENTER_ANCHOR:
    case GameConstants.TOP_RIGHT_ANCHOR:
      return value;
    case GameConstants.VCENTER_LEFT_ANCHOR:
    case GameConstants.CENTER_ANCHOR:
    case GameConstants.VCENTER_RIGHT_ANCHOR:
      return value - height / 2;
    case GameConstants.BOTTOM_LEFT_ANCHOR:
    case GameConstants.BOTTOM_HCENTER_ANCHOR:
    case GameConstants.BOTTOM_RIGHT_ANCHOR:
      return value - height;
    default:
      return value;
    }
  }

  public void setLineWidth(int lineWidth) {
    g.setLineWidth(lineWidth);
  }

  public void drawImage(GameImage image, int x, int y, int anchor) {
    if (image != null) {
      if (image.getImage() != null) {
        int width = image.getWidth();
        int height = image.getHeight();
        int realX = Sprite.calculateX(x, anchor, width);
        int realY = Sprite.calculateY(y, anchor, height);
        g.drawImage(image.getImage(), realX, realY, realX + width, realY + height, GameConstants.TOP_LEFT_ANCHOR);
        image.setLastTimeUse((int) System.currentTimeMillis());
      } else {
        if (System.currentTimeMillis() - image.getLastTimeUse() > ResourceManager.RESOURCE_IDLE_TIME) {
          ResourceManager.requestResource(image.getCategory(), image.getName());
          image.setLastTimeUse((int) System.currentTimeMillis());
        }
      }
    }
  }

  public void setClip(int x, int y, int width, int height) {
    clip.left = x;
    clip.right = x + width;
    clip.top = y;
    clip.bottom = y + height;
    g.setClippingRect(clip);
  }

  public int getColor() {
    return g.getFillColor();
  }

  public void drawLine(int x1, int y1, int x2, int y2) {
    g.drawLine(x1, y1, x2, y2);
  }

  public int getClipX() {
    g.getClippingRect(clip);
    return clip.left;
  }

  public int getClipWidth() {
    g.getClippingRect(clip);
    return PMath.abs(clip.right - clip.left);
  }

  public int getClipY() {
    g.getClippingRect(clip);
    return clip.top;
  }

  public int getClipHeight() {
    g.getClippingRect(clip);
    return PMath.abs(clip.bottom - clip.top);
  }

  public void clipRect(int x, int y, int width, int height) {
    // TODO: Graphics : clipRect : hàm này đang xử lý chưa chuẩn xác
    clip.left = x;
    clip.right = x + width;
    clip.top = y;
    clip.bottom = y + height;
    g.setClippingRect(clip);
  }

  public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {
    g.drawRoundedRect(x, y, x + width, y + height, arcWidth, arcHeight);
  }

  public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {
    int lastColor = g.getFillColor();
    g.setFillColor(Color.Transparent);
    g.setLineWidth(1);
    g.drawRoundedRect(x, y, x + width, y + height, arcWidth, arcHeight);
    g.setFillColor(lastColor);
  }

  public void drawRect(int x, int y, int width, int height) {
    int lastColor = g.getFillColor();
    g.setFillColor(Color.Transparent);
    g.setLineWidth(1);
    g.drawRect(x, y, x + width, y + height);
    g.setFillColor(lastColor);
  }
}
